using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Text;
using System.Windows.Forms;
using ComponentFactory.Krypton.Toolkit;

namespace Banshee.Controls
{
    //Cornel 23-03-2007 - The default DataGridView Flickers too much

    public class GlassGrid : DataGridView
    {

        private IPalette _palette;
        private PaletteRedirect _paletteRedirect;
        private PaletteBackInheritRedirect _paletteBack;
        private PaletteBorderInheritRedirect _paletteBorder;
        private PaletteContentInheritRedirect _paletteContent;
        private IPaletteRibbonBack _paletteRibbonBack;
        public GlassGrid()
        {
            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true);
            UpdateStyles();
            _palette = KryptonManager.CurrentGlobalPalette;
                       if (_palette != null)
                           _palette.PalettePaint += new EventHandler<PaletteLayoutEventArgs>(_palette_PalettePaint);
                       KryptonManager.GlobalPaletteChanged += new EventHandler(KryptonManager_GlobalPaletteChanged);
            BorderStyle = BorderStyle.None;
            // ...your other constructor code...

            // (1) Create redirection object to the base palette
            _paletteRedirect = new PaletteRedirect(_palette);

            // (2) Create accessor objects for the back, border and content
            _paletteBack = new PaletteBackInheritRedirect(_paletteRedirect);
            _paletteBorder = new PaletteBorderInheritRedirect(_paletteRedirect);
            _paletteContent = new PaletteContentInheritRedirect(_paletteRedirect);
            _paletteRibbonBack = new PaletteRibbonBackInheritRedirect(_paletteRedirect,PaletteRibbonBackStyle.RibbonTab);
        }

        void KryptonManager_GlobalPaletteChanged(object sender, EventArgs e)
        {
            // (5) Unhook events from old palette
            if (_palette != null)
                _palette.PalettePaint -= new EventHandler<PaletteLayoutEventArgs>(_palette_PalettePaint);

            // (6) Cache the new IPalette that is the global palette
            _palette = KryptonManager.CurrentGlobalPalette;

            // (7) Hook into events for the new palette
            if (_palette != null)
                _palette.PalettePaint += new EventHandler<PaletteLayoutEventArgs>(_palette_PalettePaint);

            // (8) Change of palette means we should repaint to show any changes
            Invalidate();

        }

        void _palette_PalettePaint(object sender, PaletteLayoutEventArgs e)
        {
            Invalidate();
        }
        protected override void OnRowPrePaint(DataGridViewRowPrePaintEventArgs e)
        {


            if ((e.State & DataGridViewElementStates.Selected) ==
                     DataGridViewElementStates.Selected && this.SelectionMode == DataGridViewSelectionMode.FullRowSelect)
            {
                e.PaintParts &= ~DataGridViewPaintParts.Background;
                Rectangle rect = new Rectangle(
                 0, e.RowBounds.Top,
                 Columns.GetColumnsWidth(
                     DataGridViewElementStates.Visible) -
                 HorizontalScrollingOffset + 1,
                 e.RowBounds.Height);

                Color SelectedLightColor = Color.FromArgb(251, 230, 148);
                Color SelectedDarkColor = Color.FromArgb(251, 150, 60);
                DrawingMethods.DrawGlassGradient(e.Graphics, rect, SelectedLightColor, SelectedDarkColor, 90F);

            }
            else if (SelectionMode == DataGridViewSelectionMode.CellSelect)
            {
                e.PaintParts &= ~DataGridViewPaintParts.Border;
                e.PaintParts &= ~DataGridViewPaintParts.Background;
                e.PaintParts &= ~DataGridViewPaintParts.Focus;
                for (int i = 0; i < Rows[e.RowIndex].Cells.Count; i++)
                {
                    DataGridViewCell cell = Rows[e.RowIndex].Cells[i];
                    if (cell.Selected)
                    {
                        Rectangle rect = cell.ContentBounds;
                        if (rect.Height > 0 && rect.Width > 0)
                        {
                            e.Graphics.FillRectangle(Brushes.White, rect);
                            DrawingMethods.DrawHighlight(e.Graphics, rect, DrawingMethods.Selected, DrawingMethods.Hilight);
                        }
                    }

                }


            }
            else
            {
                base.OnRowPrePaint(e);
            }
        }

        protected override void OnCellPainting(DataGridViewCellPaintingEventArgs e)
        {
            //Graphics g = e.Graphics;

           /* if (e.RowIndex == -1)
            {
                if (_palette != null)
                {
                    IRenderer renderer = _palette.GetRenderer();
                    using (RenderContext renderContext = new RenderContext(this, e.Graphics, e.CellBounds, renderer))
                    {
                        /*renderer.RenderRibbon.DrawRibbonBack(renderContext, e.CellBounds, PaletteState.Normal,_paletteRibbonBack,
                            true, null);*/

                     //   renderer.RenderStandardBack.DrawBack(renderContext,e.ClipBounds,
                   // }
                   // Console.WriteLine("Custom Cell Painted");
                    /*g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SystemDefault;
                    g.SmoothingMode = SmoothingMode.AntiAlias;
                    g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                    g.CompositingQuality = CompositingQuality.HighQuality;
                    DataGridViewColumn col = this.Columns[e.ColumnIndex];

                    if (e.RowIndex == -1)
                    {
                        /*if (col.Selected)
                        {
                            using (LinearGradientBrush brush = new LinearGradientBrush(e.CellBounds, Color.WhiteSmoke, Color.FromArgb(83,83,83), LinearGradientMode.Vertical))
                            {
                                g.FillRectangle(brush, e.CellBounds);
                            }
                            //RenderHotGlass(g, e.CellBounds);
                            e.Paint(e.ClipBounds, DataGridViewPaintParts.All & ~DataGridViewPaintParts.Background);
                            e.Handled = true;
                        }
                        else
                        {
                        //RenderGlass(g, e.CellBounds);
                        //Rendering.DrawingMethods.DrawGlassBackGround(e.CellBounds, g);
                        using (LinearGradientBrush brush = new LinearGradientBrush(e.CellBounds, Color.FromArgb(83, 83, 83), SystemColors.Control, LinearGradientMode.Vertical))
                        {
                            g.FillRectangle(brush, e.CellBounds);
                        }
                        e.Paint(e.ClipBounds, DataGridViewPaintParts.All & ~DataGridViewPaintParts.Background);
                        e.Handled = true;
                        //}
                     *

                }
                else
                {
                    base.OnCellPainting(e);
                }
            }
            else
            {
                base.OnCellPainting(e);
            }*/
        base.OnCellPainting(e);
        }

        private void DrawColumnHeaders(Graphics g)
        {
            int h = this.ColumnHeadersHeight;
            int pos;
            if (RowHeadersVisible)
            {
                pos = RowHeadersWidth;
                Rectangle rect = new Rectangle(0, 0, pos, h);
                RenderGlass(g, rect);
            }
            else
                pos = 1;
            for (int i = 0; i < this.Columns.Count; i++)
            {
                StringFormat sf = new StringFormat();
                sf.Alignment = StringAlignment.Near;
                sf.LineAlignment = StringAlignment.Near;
                sf.Trimming = StringTrimming.EllipsisCharacter;
                DataGridViewColumn col = Columns[i];
                Font fn = ColumnHeadersDefaultCellStyle.Font;
                SolidBrush textbrush = new SolidBrush(col.HeaderCell.Style.ForeColor);
                string text = col.HeaderText;
                Rectangle colrect = new Rectangle(pos, 1, col.Width, h);
                if (col.Visible && colrect.Height > 0 && colrect.Width > 0)
                {
                    if (hot && col.Index == hotindex)
                        RenderHotGlass(g, colrect);
                    else
                        RenderGlass(g, colrect);
                    g.DrawString(text, fn, Brushes.Black, colrect.X + 2, colrect.Y + (h / 4) - 2, sf);
                    pos += col.Width;
                }
            }
        }
        public static void RenderGlass(Graphics g, Rectangle rect)
        {
            Color[] col = new Color[] { Color.FromArgb(210, 214, 221), Color.FromArgb(193, 198, 207), Color.FromArgb(180, 187, 197), Color.FromArgb(231, 240, 241) };
            float[] pos = new float[] { 0.0f, 0.2f, 0.2f, 1.0f };

            ColorBlend blend = new ColorBlend();
            blend.Colors = col;
            blend.Positions = pos;
            LinearGradientBrush brush = new LinearGradientBrush(rect, Color.Transparent, Color.Transparent, LinearGradientMode.Vertical);
            brush.InterpolationColors = blend;
            g.FillRectangle(brush, rect);
            rect.Offset(1, 1);
            rect.Width -= 2;
            rect.Height -= 2;
        }
        public static void RenderHotGlass(Graphics g, Rectangle rect)
        {
            Color[] col = new Color[] { Color.FromArgb(254, 216, 170), Color.FromArgb(251, 181, 101), Color.FromArgb(250, 157, 52), Color.FromArgb(253, 238, 170) };
            float[] pos = new float[] { 0.0f, 0.2f, 0.2f, 1.0f };

            ColorBlend blend = new ColorBlend();
            blend.Colors = col;
            blend.Positions = pos;
            LinearGradientBrush brush = new LinearGradientBrush(rect, Color.Transparent, Color.Transparent, LinearGradientMode.Vertical);
            brush.InterpolationColors = blend;
            g.FillRectangle(brush, rect);
            rect.Offset(1, 1);
            rect.Width -= 2;
            rect.Height -= 2;
        }

        protected override void OnColumnDisplayIndexChanged(DataGridViewColumnEventArgs e)
        {
            base.OnColumnDisplayIndexChanged(e);
        }
        private int hotindex = 0;
        private bool hot;
        private bool showDataError;

        public bool ShowDataError
        {
            get { return showDataError; }
            set { showDataError = value; }
        }
        protected override void OnDataError(bool displayErrorDialogIfNoHandler, DataGridViewDataErrorEventArgs e)
        {
            base.OnDataError(showDataError, e);
        }

    }
    static class DrawingMethods
    {
        public static Color SelectedLightColor = Color.FromArgb(251, 230, 148);
        public static Color SelectedDarkColor = Color.FromArgb(251, 150, 60);
        public static Color Selected = Color.FromArgb((int)(Color.FromArgb(200, Color.White).A * 1), Color.FromArgb(200, Color.White));
        public static Color Hilight = Color.FromArgb((int)Color.Orange.A * 1, Color.Orange);
        public static void DrawHighlight(Graphics g, Rectangle rectangle, Color SelectedColor, Color HighLight)
        {
            Color FillColor = HighLight;
            g.InterpolationMode = InterpolationMode.HighQualityBilinear;
            g.CompositingQuality = CompositingQuality.HighQuality;
            using (SolidBrush ForeBrush = new SolidBrush(FillColor))
            {
                g.FillRectangle(ForeBrush, rectangle);
            }
            using (LinearGradientBrush Brush = new LinearGradientBrush(rectangle, SelectedColor, Color.Transparent, LinearGradientMode.Vertical))
            {
                float[] pos = new float[] { 0.0f, 0.40f, 0.5f, 1.0f };
                float[] factors = new float[] { 0f, 0.35f, 1f, 0.3f };
                Blend ColorBlend = new Blend(4);
                ColorBlend.Factors = factors;
                ColorBlend.Positions = pos;
                Brush.Blend = ColorBlend;
                g.FillRectangle(Brush, rectangle);
            }
        }
        public static void DrawGlassGradient(Graphics g, Rectangle rect, Color LightColor, Color DarkColor, float Angle)
        {
            Rectangle r = rect;
            if (r.Width == 0 || r.Height == 0)
                return;
            Blend glassBlend = new Blend(4);
            glassBlend.Positions[0] = 0f;
            glassBlend.Factors[0] = 0.0f;
            glassBlend.Positions[1] = 0.41f;
            glassBlend.Factors[1] = 0.4f;
            glassBlend.Positions[2] = 0.41f;
            glassBlend.Factors[2] = 0.6f;
            glassBlend.Positions[3] = 1f;
            glassBlend.Factors[3] = 0.2f;

            g.InterpolationMode = InterpolationMode.HighQualityBilinear;
            g.CompositingQuality = CompositingQuality.HighQuality;
            using (LinearGradientBrush lgb = new LinearGradientBrush(r, LightColor, DarkColor, Angle))
            {
                lgb.Blend = glassBlend;
                g.FillRectangle(lgb, r);
            }
        }
    }
}
